package pe.com.rimac.portal.service.facturacion.impl;

import java.rmi.RemoteException;

import org.apache.commons.lang.Validate;

import pe.com.rimac.portal.common.config.ServiceConfig;
import pe.com.rimac.portal.common.exception.ServiceException;
import pe.com.rimac.portal.service.facturacion.PersonaService;
import pe.com.rimac.portal.service.facturacion.modelo.Contacto;
import pe.com.rimac.portal.service.facturacion.modelo.Persona;
import pe.com.rimac.portal.service.facturacion.modelo.Persona.TipoDocumentoValidacion;
import pe.com.rimac.portal.service.facturacion.modelo.Resultado;
import pe.com.rimac.portal.service.facturacion.modelo.TipoDocumento;
import pe.com.rimac.portal.service.facturacion.modelo.TipoPersona;

import com.rimac.factelect.ejb.proxy.RetornoFacadeProxy;
import com.rimac.factelecws.vo.ParametrosValidacionPersonaVO;
import com.rimac.factelecws.vo.PersonaContactoVO;
import com.rimac.factelecws.vo.RptaProcesoVO;

public class PersonaServiceImpl implements PersonaService
{
	private static final String PERSONA_NATURAL = "P";
	private static final String PERSONA_JURIDICA = "J";
	// No se ha establecido el codigo en la enumeracion para que no se utilice para las comparaciones, ya que el
	// servicio puede cambiar los valores.
	private static final String RUC = "1";
	private static final String DNI = "2";
	private static final String CARNE_DE_EXTRANJERIA = "4";
	private static final String PASAPORTE = "6";
	private static final String FACTURA = "F";
	private static final String POLIZA = "P";
	private ServiceConfig serviceConfig;
	private RetornoFacadeProxy port;

	public PersonaServiceImpl(ServiceConfig serviceConfig)
	{
		this.serviceConfig = serviceConfig;
		this.port = new RetornoFacadeProxy();
		this.port.setEndpoint(this.serviceConfig.getProperty("facturacion.ws.url"));
	}

	@Override
	public Resultado validarPersona(Persona persona)
	{
		validarDatosPersona(persona);
		ParametrosValidacionPersonaVO pv = convertirAParametrosValidacion(persona);
		RptaProcesoVO rpta = null;
		try
		{
			rpta = port.validaExistePersona(pv);
		}
		catch (RemoteException e)
		{
			throw new ServiceException("Ocurrio un error al validar la persona.", e);
		}
		if (rpta == null)
		{
			return new Resultado();
		}
		return convertirAResultado(rpta);
	}

	@Override
	public Resultado registrarContacto(Contacto contacto)
	{
		validarContacto(contacto);
		PersonaContactoVO pc = convertirAPersonaContacto(contacto);
		RptaProcesoVO rpta = null;
		try
		{
			rpta = port.regContacto(pc);
		}
		catch (RemoteException e)
		{
			throw new ServiceException("Ocurrio un error al registrar el contacto.", e);
		}
		if (rpta == null)
		{
			return new Resultado();
		}
		return convertirAResultado(rpta);
	}

	private ParametrosValidacionPersonaVO convertirAParametrosValidacion(Persona persona)
	{
		ParametrosValidacionPersonaVO pv = new ParametrosValidacionPersonaVO();
		if (TipoPersona.PERSONA_JURIDICA.equals(persona.getTipoPersona()))
		{
			pv.setTipoPersona(PERSONA_JURIDICA);
		}
		else
		{
			pv.setTipoPersona(PERSONA_NATURAL);
		}
		if (TipoDocumento.RUC.equals(persona.getTipoDocumento()))
		{
			pv.setTipoDocPersona(RUC);
		}
		else
		{
			pv.setTipoDocPersona(DNI);
		}
		pv.setNumDocPersona(persona.getNumeroDocumento());
		if (TipoDocumentoValidacion.FACTURA.equals(persona.getTipoDocumentoValidacion()))
		{
			pv.setTipoDocValidacion(FACTURA);
			pv.setSerieFactura(persona.getSerieFactura());
			pv.setNumFactura(persona.getNumeroFactura());
		}
		else
		{
			pv.setTipoDocValidacion(POLIZA);
			pv.setCodProducto(persona.getCodigoProducto());
			pv.setNumPol(persona.getNumeroPoliza());
		}
		pv.setCodCia(persona.getCodigoCompania());
		return pv;
	}

	private Resultado convertirAResultado(RptaProcesoVO rpta)
	{
		Resultado rv = new Resultado();
		rv.setCodigo(rpta.getResultado());
		rv.setDescripcion(rpta.getDescripcion());
		rv.setValor(rpta.getValor());
		return rv;
	}

	private PersonaContactoVO convertirAPersonaContacto(Contacto contacto)
	{
		PersonaContactoVO pc = new PersonaContactoVO();
		if (TipoPersona.PERSONA_JURIDICA.equals(contacto.getTipoCliente()))
		{
			pc.setTipoCliente(PERSONA_JURIDICA);
		}
		else
		{
			pc.setTipoCliente(PERSONA_NATURAL);
		}
		if (TipoDocumento.RUC.equals(contacto.getTipoDocumentoCliente()))
		{
			pc.setTipoDocCliente(RUC);
		}
		else
		{
			pc.setTipoDocCliente(DNI);
		}
		pc.setNumDocCliente(contacto.getNumeroDocumentoCliente());
		pc.setNombres(contacto.getNombres());
		pc.setApelidoPaterno(contacto.getApellidoPaterno());
		pc.setApellidoMaterno(contacto.getApellidoMaterno());
		if (TipoDocumento.DNI.equals(contacto.getTipoDocumento()))
		{
			pc.setTipoDocumento(DNI);
		}
		else if (TipoDocumento.CARNE_DE_EXTRANJERIA.equals(contacto.getTipoDocumento()))
		{
			pc.setTipoDocumento(CARNE_DE_EXTRANJERIA);
		}
		else if (TipoDocumento.PASAPORTE.equals(contacto.getTipoDocumento()))
		{
			pc.setTipoDocumento(PASAPORTE);
		}
		pc.setNumDocumento(contacto.getNumeroDocumento());
		pc.setCorreoElectronico(contacto.getEmail());
		pc.setCargo(contacto.getCargo());
		pc.setTelefono(contacto.getTelefono());
		pc.setAnexo(contacto.getAnexo());
		pc.setPreguntaSeguridad(contacto.getPreguntaSeguridad());
		pc.setRespuestaSeguridad(contacto.getRespuestaSeguridad());
		return pc;
	}

	private void validarContacto(Contacto contacto)
	{
		Validate.notNull(contacto, "El contacto no puede ser null.");
		Validate.notEmpty(contacto.getNombres(), "El nombre del contacto no puede ser null.");
		Validate.notEmpty(contacto.getApellidoPaterno(), "El apellido paterno no puede ser null.");
		Validate.notEmpty(contacto.getApellidoMaterno(), "El apellido materno no puede ser null.");
		Validate.notNull(contacto.getTipoDocumento(), "El tipo de documento no puede ser null.");
		Validate.notNull(contacto.getTipoCliente(), "El tipo de cliente no puede ser null.");
		Validate.notNull(contacto.getTipoDocumentoCliente(), "El tipo de documento del cliente no puede ser null.");
		Validate.notEmpty(contacto.getNumeroDocumentoCliente(), "El numero de documeno del cliente no puede ser null.");
		Validate.notEmpty(contacto.getPreguntaSeguridad(), "La pregunta de seguridad no puede ser null.");
		Validate.notEmpty(contacto.getRespuestaSeguridad(), "La respuesta de seguridad no puede ser null.");
		Validate.notEmpty(contacto.getEmail(), "El correo electronico no puede ser null.");
	}

	private void validarDatosPersona(Persona persona)
	{
		Validate.notNull(persona, "La persona no puede ser null.");
		Validate.notEmpty(persona.getCodigoCompania(), "El codigo de la compania no puede ser null.");
		Validate.notNull(persona.getTipoPersona(), "El tipo de persona no puede ser null.");
		Validate.notNull(persona.getTipoDocumento(), "El tipo de documento no puede ser null.");
		Validate.notEmpty(persona.getNumeroDocumento(), "El numero de documento no puede ser null.");
		Validate.notNull(persona.getTipoDocumentoValidacion(), "El tipo de documento de validacion no puede ser null.");
	}
}
